package com.mh.service.impl;

import com.google.gson.Gson;
import com.mh.dto.R;
import com.mh.dto.bo.WeChatSessionModel;
import com.mh.dto.vo.GoodsStartVo;
import com.mh.pojo.GoodsInfos;
import com.mh.pojo.UserInfos;
import com.mh.service.UserInfosService;
import com.mh.utils.JWTUtils;
import com.mongodb.client.result.UpdateResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.*;

/**
 * Date:2024/10/18
 * author:zmh
 * description: 用户信息服务类实现
 **/


@RequiredArgsConstructor
@Slf4j
@Service
public class UserInfoServiceImpl implements UserInfosService {

    @Value("${APPID}")
    private String appid;

    @Value("${APPSECRET}")
    private String appsecret;

    // 向微信服务器发送请求获取openID
    private final RestTemplate restTemplate;

    private final MongoTemplate mongoTemplate;


    /**
     * 登录验证
     * @param code 临时登录码
     * @return ·
     */
    @Override
    public Map<String, Object> checkLogin(String code) {

        // 用于返回登录结果
        Map<String,Object> map = new HashMap<>();

        // 根据传入code，调用微信服务器，获取唯一openid
        // 微信服务器接口地址
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+appid+ "&secret="+appsecret
                +"&js_code="+ code +"&grant_type=authorization_code";
        String errmsg = "";
        String errcode = "";
        String session_key = "";
        String openid = "";
        WeChatSessionModel weChatSessionModel;
        // 发送请求，获取openID
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
        if(responseEntity.getStatusCode() == HttpStatus.OK) {
            String sessionData = responseEntity.getBody();
            Gson gson = new Gson();
            //将json字符串转化为实体类;
            weChatSessionModel = gson.fromJson(sessionData, WeChatSessionModel.class);
            log.info("返回的数据==>{}",weChatSessionModel);
            //获取用户的唯一标识
            openid = weChatSessionModel.getOpenid();
            //获取会话秘钥（具有时效性，用户登录的临时通行证）
            //登录后前端的每次接口请求都需带上session_key
            session_key = weChatSessionModel.getSession_key();
            //获取错误码
            errcode = weChatSessionModel.getErrcode();
            //获取错误信息
            errmsg = weChatSessionModel.getErrmsg();
        }else{
            log.info("出现错误，错误信息：{}",errmsg );
            map.put("errmsg",errmsg);
            return map;
        }

        // 判断是否成功获取到openid
        if ("".equals(openid) || openid == null){
            log.info("错误获取openid,错误信息:{}",errmsg);
            map.put("errmsg",errmsg);
            return map;
        }else{
            // 判断用户是否存在
            // 构造查询条件
            Query openIdQuery = new Query(Criteria.where("openId").is(openid));
            UserInfos userInfo = mongoTemplate.findOne(openIdQuery, UserInfos.class);
            // 不存在，加入数据库 （走注册逻辑）
            if (userInfo == null){
                // 填充初始信息
                UserInfos newUser = new UserInfos(UUID.randomUUID().toString(), openid, "微信用户", "default.jpg", new ArrayList<UserInfos.Coupon>(), new ArrayList<String>(), LocalDateTime.now().toString());
                mongoTemplate.insert(newUser);
                map.put("user", newUser);
                String token = JWTUtils.createToken(newUser.getUserId());
                map.put("token",token);
                return map;
            }else{
                // 存在，将用户信息加入map返回
                map.put("user",userInfo);
                String token = JWTUtils.createToken(userInfo.getUserId().toString());
                map.put("token",token);
                return map;
            }
        }
    }

    /**
     * 检查用户是否收藏某商品
     * @param userId 用户ID
     * @param goodsId 商品ID
     * @return 是否收藏
     */
    @Override
    public R<Boolean> checkGoodsStart(String userId, String goodsId) {
        // 根据用户ID查出用户信息，在根据用户信息中的收藏商品列表检查是否收藏商品
        Query query = new Query(Criteria.where("userId").is(userId));
        UserInfos userInfo = mongoTemplate.findOne(query, UserInfos.class);
        if(userInfo == null){
            return R.error("用户不存在");
        }

        if (userInfo.getGoodsCollects().contains(goodsId)) {
            return R.success(true);
        } else {
            return R.success(false);
        }
    }

    /**
     * 更新用户收藏商品
     * @param goodsStartVo 商品收藏信息
     * @return 是否成功
     */
    @Override
    public R<Boolean> updateGoodsStart(GoodsStartVo goodsStartVo) {
        // 根据用户ID查出用户信息，在根据用户信息中的收藏商品列表检查是否收藏商品
        Query query = new Query(Criteria.where("userId").is(goodsStartVo.getUserId()));
        UserInfos userInfo = mongoTemplate.findOne(query, UserInfos.class);
        if(userInfo == null){
            return R.error("用户不存在");
        }

        Update update = new Update();

        Boolean flag = false;

        // 检查商品是否已经在用户收藏列表之中
        if (userInfo.getGoodsCollects().contains(goodsStartVo.getGoodsId())) {
            flag = true;
        }

        // 根据传入操作字符串判断需要执行的更新操作
        if (goodsStartVo.getOps().equals("start") && !flag) {
            update.addToSet("goodsCollects", goodsStartVo.getGoodsId());
            return execUpdate(query, update);
        } else if (goodsStartVo.getOps().equals("disStart") && flag) {
            update.pull("goodsCollects", goodsStartVo.getGoodsId());
            return execUpdate(query, update);
        } else {
            return R.error("更新失败");
        }
    }

    /**
     * 获取指定用户收藏的商品
     * @param userId 用户ID
     * @return ·
     */
    @Override
    public R<List<GoodsInfos>> getGoodsStartByUserId(String userId) {
        // 根据用户ID获取用户信息
        Query query = new Query(Criteria.where("userId").is(userId));
        UserInfos userInfo = mongoTemplate.findOne(query, UserInfos.class);
        // 取出收藏商品ID列表
        List<String> goodsCollects = userInfo.getGoodsCollects();

        // 构造查询条件
        Query goodsQuery = new Query(Criteria.where("goodsId").in(goodsCollects));
        List<GoodsInfos> goodsInfos = mongoTemplate.find(goodsQuery, GoodsInfos.class);
        if (goodsInfos.size() > 0) {
            return R.success(goodsInfos);
        }
        return R.error("获取收藏商品失败");
    }

    // 封装执行更新函数
    public R<Boolean> execUpdate(Query query, Update update){
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, UserInfos.class);

        if (updateResult.getMatchedCount() == 0) {
            return R.error("更新失败");
        }

        return R.success(true);
    }
}




